/*
 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package com.oracle.svm.core.posix.headers;

import org.graalvm.nativeimage.c.CContext;
import org.graalvm.nativeimage.c.function.CFunction;
import org.graalvm.nativeimage.c.type.CIntPointer;

/**
 * Contains definitions from sys/wait.h that we need.
 */
@CContext(PosixDirectives.class)
public class Wait {
    /* Allow lower-case type names: Checkstyle: stop. */

    @CFunction
    public static native int flock(int fd, int operation);

    /*
     * Operating system dependency: The C function returns a pid_t, which happens to be an int on
     * both Darwin and Linux, but it does not have to be an int on all platforms.
     */
    @CFunction
    public static native int wait(CIntPointer stat_loc);

    /**
     * pid_t waitpid(pid_t pid, int *stat_loc, int options);
     */
    @CFunction
    public static native int waitpid(int pid, CIntPointer stat_loc, int options);

    /*
     * The following are C macros (sys/wait.h) for interpreting the status from waitpid() and
     * wait(), but their behavior and the composition of the status is the same across platforms so
     * we replicate them (OpenJDK does that too)
     */

    public static boolean WIFEXITED(int status) {
        return (((status) & 0xFF) == 0);
    }

    public static int WEXITSTATUS(int status) {
        return (((status) >> 8) & 0xFF);
    }

    public static boolean WIFSIGNALED(int status) {
        return (((status) & 0xFF) > 0 && ((status) & 0xFF00) == 0);
    }

    public static int WTERMSIG(int status) {
        return ((status) & 0x7F);
    }

    /* Allow lower-case type names: Checkstyle: resume. */
}
